//This file is automatically rebuilt by the Cesium build process.
export default "#ifndef HAS_SPLAT_TEXTURE\n\
\n\
void calcCov3D(vec3 scale, vec4 rot, out float[6] cov3D)\n\
{\n\
    mat3 S = mat3(\n\
        u_splatScale * scale[0], 0, 0,\n\
        0, u_splatScale * scale[1], 0,\n\
        0, 0, u_splatScale * scale[2]\n\
    );\n\
\n\
    float r = rot.w;\n\
    float x = rot.x;\n\
    float y = rot.y;\n\
    float z = rot.z;\n\
\n\
    // Compute rotation matrix from quaternion\n\
    mat3 R = mat3(\n\
        1. - 2. * (y * y + z * z),\n\
        2. * (x * y - r * z),\n\
        2. * (x * z + r * y),\n\
        2. * (x * y + r * z),\n\
        1. - 2. * (x * x + z * z),\n\
        2. * (y * z - r * x),\n\
        2. * (x * z - r * y),\n\
        2. * (y * z + r * x),\n\
        1. - 2. * (x * x + y * y)\n\
    );\n\
\n\
    mat3 M = S * R;\n\
    mat3 Sigma = transpose(M) * M;\n\
\n\
    //we only need part of it, symmetric\n\
    cov3D = float[6](\n\
        Sigma[0][0], Sigma[0][1], Sigma[0][2],\n\
        Sigma[1][1], Sigma[1][2], Sigma[2][2]\n\
    );\n\
\n\
}\n\
\n\
vec3 calcCov2D(vec3 worldPos, float focal_x, float focal_y, float tan_fovx, float tan_fovy, float[6] cov3D, mat4 viewmatrix) {\n\
    vec4 t = viewmatrix * vec4(worldPos, 1.0);\n\
\n\
    float limx = 1.3 * tan_fovx;\n\
    float limy = 1.3 * tan_fovy;\n\
    float txtz = t.x / t.z;\n\
    float tytz = t.y / t.z;\n\
    t.x = min(limx, max(-limx, txtz)) * t.z;\n\
    t.y = min(limy, max(-limy, tytz)) * t.z;\n\
\n\
    mat3 J = mat3(\n\
        focal_x / t.z, 0, -(focal_x * t.x) / (t.z * t.z),\n\
        0, focal_y / t.z, -(focal_y * t.y) / (t.z * t.z),\n\
        0, 0, 0\n\
    );\n\
\n\
   mat3 W =  mat3(\n\
        viewmatrix[0][0], viewmatrix[1][0], viewmatrix[2][0],\n\
        viewmatrix[0][1], viewmatrix[1][1], viewmatrix[2][1],\n\
        viewmatrix[0][2], viewmatrix[1][2], viewmatrix[2][2]\n\
    );\n\
    mat3 T = W * J;\n\
    mat3 Vrk = mat3(\n\
        cov3D[0], cov3D[1], cov3D[2],\n\
        cov3D[1], cov3D[3], cov3D[4],\n\
        cov3D[2], cov3D[4], cov3D[5]\n\
    );\n\
\n\
    mat3 cov = transpose(T) * transpose(Vrk) * T;\n\
\n\
    cov[0][0] += .3;\n\
    cov[1][1] += .3;\n\
    return vec3(cov[0][0], cov[0][1], cov[1][1]);\n\
}\n\
\n\
\n\
void gaussianSplatStage(ProcessedAttributes attributes, inout vec4 positionClip) {\n\
    mat4 viewMatrix = czm_modelView;\n\
\n\
    vec4 clipPosition = czm_modelViewProjection * vec4(a_splatPosition,1.0);\n\
    positionClip = clipPosition;\n\
\n\
    //positionClip *= u_scalingMatrix;\n\
\n\
    float[6] cov3D;\n\
    calcCov3D(attributes.scale, attributes.rotation, cov3D);\n\
    vec3 cov = calcCov2D(a_splatPosition, u_focalX, u_focalY, u_tan_fovX, u_tan_fovY, cov3D, viewMatrix);\n\
\n\
    float mid = (cov.x + cov.z) / 2.0;\n\
    float radius = length(vec2((cov.x - cov.z) / 2.0, cov.y));\n\
    float lambda1 = mid + radius, lambda2 = mid - radius;\n\
\n\
    if(lambda2 < 0.0) return;\n\
    vec2 diagonalVector = normalize(vec2(cov.y, lambda1 - cov.x));\n\
    vec2 v1 = min(sqrt(2.0 * lambda1), 1024.0) * diagonalVector;\n\
    vec2 v2 = min(sqrt(2.0 * lambda2), 1024.0) * vec2(diagonalVector.y, -diagonalVector.x);\n\
\n\
    vec2 corner = vec2((gl_VertexID << 1) & 2, gl_VertexID & 2) - 1.;\n\
    positionClip += vec4((corner.x * v1 + corner.y * v2) * 4.0 / czm_viewport.zw * positionClip.w, 0, 0);\n\
    positionClip.z = clamp(positionClip.z, -abs(positionClip.w), abs(positionClip.w));\n\
    v_vertPos = corner ;\n\
    v_splatColor = a_splatColor;\n\
}\n\
\n\
#else\n\
\n\
vec4 calcCovVectors(vec3 worldPos, mat3 Vrk, mat3 viewmatrix) {\n\
    vec4 t = vec4(worldPos, 1.0);\n\
    float focal = czm_viewport.z * czm_projection[0][0];\n\
\n\
    float J1 = focal / t.z;\n\
    vec2 J2 = -J1 / t.z * t.xy;\n\
    mat3 J = mat3(\n\
        J1, 0.0, J2.x,\n\
        0.0, J1, J2.y,\n\
        0.0, 0.0, 0.0\n\
    );\n\
\n\
    //assuming a uniform scale, should get us close enough\n\
    float scale = length(viewmatrix[0]);\n\
\n\
    mat3 T = viewmatrix * J;\n\
    mat3 cov = transpose(T) * Vrk * T / (scale*scale);\n\
\n\
    float diagonal1 = cov[0][0] + .3;\n\
    float offDiagonal = cov[0][1];\n\
    float diagonal2 = cov[1][1] + .3;\n\
\n\
    float mid = 0.5 * (diagonal1 + diagonal2);\n\
    float radius = length(vec2((diagonal1 - diagonal2) * 0.5, offDiagonal));\n\
    float lambda1 = mid + radius;\n\
    float lambda2 = max(mid - radius, 0.1);\n\
\n\
    vec2 diagonalVector = normalize(vec2(offDiagonal, lambda1 - diagonal1));\n\
\n\
    return vec4(\n\
        min(sqrt(2.0 * lambda1), 1024.0) * diagonalVector,\n\
        min(sqrt(2.0 * lambda2), 1024.0) * vec2(diagonalVector.y, -diagonalVector.x)\n\
    );\n\
}\n\
\n\
highp vec4 discardVec = vec4(0.0, 0.0, 2.0, 1.0);\n\
\n\
void gaussianSplatStage(ProcessedAttributes attributes, inout vec4 positionClip) {\n\
    uint texIdx = uint(a_splatIndex);\n\
    ivec2 posCoord = ivec2((texIdx & 0x3ffu) << 1, texIdx >> 10);\n\
    vec4 splatPosition = vec4( uintBitsToFloat(uvec4(texelFetch(u_splatAttributeTexture, posCoord, 0))) );\n\
    \n\
    vec4 splatViewPos = czm_modelView * vec4(splatPosition.xyz, 1.0);\n\
    vec4 clipPosition = czm_projection * splatViewPos;\n\
\n\
    float clip = 1.2 * clipPosition.w;\n\
    if (clipPosition.z < -clip || clipPosition.x < -clip || clipPosition.x > clip ||\n\
        clipPosition.y < -clip || clipPosition.y > clip) {\n\
        positionClip = vec4(0.0, 0.0, 2.0, 1.0);\n\
        return;\n\
    }\n\
\n\
    ivec2 covCoord = ivec2(((texIdx & 0x3ffu) << 1) | 1u, texIdx >> 10);\n\
    uvec4 covariance = uvec4(texelFetch(u_splatAttributeTexture, covCoord, 0));\n\
\n\
    positionClip = clipPosition;\n\
\n\
    vec2 u1 = unpackHalf2x16(covariance.x) ;\n\
    vec2 u2 = unpackHalf2x16(covariance.y);\n\
    vec2 u3 = unpackHalf2x16(covariance.z);\n\
    mat3 Vrk = mat3(u1.x, u1.y, u2.x, u1.y, u2.y, u3.x, u2.x, u3.x, u3.y);\n\
\n\
    //we can still apply scale here even though cov3d is pre-computed\n\
    Vrk *= u_splatScale;\n\
\n\
    vec4 covVectors = calcCovVectors(\n\
        splatViewPos.xyz,\n\
        Vrk,\n\
        mat3(transpose(czm_modelView))\n\
    );\n\
\n\
    if (dot(covVectors.xy, covVectors.xy) < 4.0 && dot(covVectors.zw, covVectors.zw) < 4.0) {\n\
        gl_Position = discardVec;\n\
        return;\n\
    }\n\
\n\
    vec2 corner = vec2((gl_VertexID << 1) & 2, gl_VertexID & 2) - 1.;\n\
\n\
    positionClip += vec4((corner.x * covVectors.xy + corner.y * covVectors.zw) / czm_viewport.zw * positionClip.w, 0, 0);\n\
    positionClip.z = clamp(positionClip.z, -abs(positionClip.w), abs(positionClip.w));\n\
\n\
    v_vertPos = corner ;\n\
    v_splatColor = vec4(covariance.w & 0xffu, (covariance.w >> 8) & 0xffu, (covariance.w >> 16) & 0xffu, (covariance.w >> 24) & 0xffu) / 255.0;\n\
\n\
    //if tile bounding volumes are shown, increase transparency so we can see the entire box\n\
    #ifdef DEBUG_BOUNDING_VOLUMES\n\
    v_splatColor.a *= 0.08;\n\
    #endif\n\
}\n\
\n\
\n\
#endif\n\
";
